import { _decorator, Component, JsonAsset, Node, resources } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('MapGenerate')
export class MapGenerate extends Component {
    // 地图的大小
    @property
    mapSize: number = 15;

    // 地图组成地点及其生成概率
    @property({ type: [String, Number] })
    mapElements: { element: string, probability: number }[] = [
        { element: '村庄', probability: 0.1 },
        { element: '城镇', probability: 0.05 },
        { element: '森林', probability: 0.2 },
        { element: '山地', probability: 0.15 },
        { element: '河流', probability: 0.1 },
        { element: '旷野', probability: 0.1 },
        { element: '平原', probability: 0.2 },
        { element: '草原', probability: 0.1 },
        { element: '荒地', probability: 0.05 },
        { element: '河滩', probability: 0.05 },
        { element: '沼泽', probability: 0.05 },
        { element: '沙地', probability: 0.05 },
        { element: '雪地', probability: 0.05 }
    ];

    // 生成密度，范围从 0 到 1，表示地图被填充的比例
    @property
    density: number = 0.7;

    // 连贯生成元素及其规则
    @property({ type: [String, String] })
    connectedElements: { element: string, nearElement: string }[] = [
        { element: '河流', nearElement: '山地' },
        { element: '河流', nearElement: '湖泊' },
        // { element: '道路', nearElement: '村庄' },
        // { element: '道路', nearElement: '城镇' }
    ];

    // 连贯生成元素的生成密度
    @property
    connectedDensity: number = 0.5;

    start() {
        console.log('开始生成地图\n'+this.generateMap());
        this.generateMap();
    }

    update(deltaTime: number) {

    }

    generateMap(): string[][] {
        const map: string[][] = [];

        for (let i = 0; i < this.mapSize; i++) {
            map[i] = [];
            for (let j = 0; j < this.mapSize; j++) {
                // 根据生成密度决定是否生成地点
                if (Math.random() < this.density) {
                    // 根据生成概率选择地点
                    const randomValue = Math.random();
                    let cumulativeProbability = 0;
                    for (const { element, probability } of this.mapElements) {
                        cumulativeProbability += probability;
                        if (randomValue < cumulativeProbability) {
                            map[i][j] = element;
                            break;
                        }
                    }
                } else {
                    map[i][j] = '[    ]'; // 如果不生成地点，则为空地
                }
            }
        }

        // 生成连贯元素
        this.generateConnectedElements(map);

        return map;
    }

    generateConnectedElements(map: string[][]) {
        for (const { element, nearElement } of this.connectedElements) {
            const connectedDensity = this.connectedDensity;
            for (let i = 0; i < this.mapSize; i++) {
                for (let j = 0; j < this.mapSize; j++) {
                    if (Math.random() < connectedDensity && map[i][j] === nearElement) {
                        this.generateConnectedElement(map, i, j, element);
                    }
                }
            }
        }
    }

    generateConnectedElement(map: string[][], x: number, y: number, element: string) {
        const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]; // 上下左右四个方向
        const maxLength = Math.max(this.mapSize, this.mapSize); // 最大长度
        const path: [number, number][] = [];

        for (let length = 0; length < maxLength; length++) {
            const randomDirection = directions[Math.floor(Math.random() * directions.length)];
            x += randomDirection[0];
            y += randomDirection[1];

            // 检查是否越界
            if (x < 0 || x >= this.mapSize || y < 0 || y >= this.mapSize) {
                break;
            }

            // 检查是否已经是目标元素
            if (map[x][y] === element) {
                break;
            }

            // 检查是否靠近目标元素
            if (this.findNearbyElement(map, x, y, element)) {
                map[x][y] = element;
                path.push([x, y]);
                break;
            }

            // 检查是否为空地
            if (map[x][y] === '[    ]') {
                map[x][y] = element;
                path.push([x, y]);
            }
        }

        // 回溯，确保路径连贯
        for (let i = path.length - 1; i >= 0; i--) {
            const [x, y] = path[i];
            if (!this.findNearbyElement(map, x, y, element)) {
                map[x][y] = '[    ]';
            }
        }
    }

    findNearbyElement(map: string[][], x: number, y: number, element: string): boolean {
        const directions = [[0, 1], [1, 0], [0, -1], [-1, 0]]; // 上下左右四个方向
        for (const direction of directions) {
            const newX = x + direction[0];
            const newY = y + direction[1];

            // 检查是否越界
            if (newX < 0 || newX >= this.mapSize || newY < 0 || newY >= this.mapSize) {
                continue;
            }

            // 检查是否为目标元素
            if (map[newX][newY] === element) {
                return true;
            }
        }

        return false;
    }
}
